home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------*/
- /* TOOLPACK/1 Release: 1.1 */
- /*-------------------------------*/
- #include <ctype.h>
- #include "define.h"
-
- #include <sys/types.h>
- #include <sys/time.h>
- #ifdef sgi
- #include <time.h>
- #endif
-
- #include <sys/stat.h>
-
- #include <sys/dir.h>
-
- #include "globals1.h"
- #include "globals2.h"
- #include "globals.h"
-
- acopy_(fdi, fdo, size)
- int *fdi, *fdo, *size;
-
- {
- /* copy size characters from the input file fdi to the output
- file fdo. If eof encountered on fdi before the transfer is
- complete the transfer is immediately terminated. Both files
- are assumed sequential */
-
- int c, i;
-
- /* ensure input file open for read and output file for write */
- if (opnread(*fdi) == ERR || opnwrit(*fdo) == ERR) {
- remark_("wrong mode in acopy",19L);
- return;
- }
-
- /* move the characters */
- for(i=1; i <= *size && (c=getch_(&c,fdi)) != EOF ; i++)
- putch_(&c,fdo);
-
- }
-
- cant_(name)
- int *name;
-
- {
- /* outputs the message 'CANT OPEN FILE OF NAME: ' name on stderr */
-
- int fd = STDERR, newline = NEWLINE;
-
- zchout_("CAN'T OPEN FILE OF NAME: ", &fd, 25L);
- putlin_(name, &fd);
- putch_(&newline, &fd);
-
- }
-
- close_(fd)
- int *fd;
-
- {
- /* Terminate access to the file descriptor fd. This
- routine may be used on both sequential and direct
- access files.
-
- Attempting to close a preconnected file or a closed file
- has no effect */
-
- struct fdinfo *ptr;
-
- if( checkfd(*fd) != FILES)
- /* no effect on preconnected units */
- return;
-
- ptr = &files[*fd];
-
- /* deal with no effect cases */
-
- /* if ( ptr->access == NOTOPEN)
- return; */
-
- /* set access to NOTOPEN, write out the current buffer if
- currentaccess is write and close the file */
-
- ptr->access = NOTOPEN;
- flush(*fd);
- close(*fd);
- if(DEBUG) printf("in close : just closed fd = %d\n",*fd);
- }
-
- create_( name, access)
- int *name, *access;
-
- {
- /* create a sequential file of name name and open it with
- access type access. Assign an internal file descriptor
- to the file and return this via the function name. If
- a file already exists with this name it is deleted
- prior to creation */
-
- int uid,gid,len,i;
- char newch[MAXPATH];
- struct stat sbuf;
-
- int fd, pmode;
- char charnm1[MAXPATH];
- struct fdinfo *ptr;
- struct filinfo openinf;
-
- /* generate full path name as a character string */
- mkfilnm(name, charnm1, &openinf);
-
- /* sort out possible error cases */
- switch (openinf.ftype1)
- {
- case ERR: /* error in mkpath or host file a directory */
- return(ERR);
-
- case DEVICE: /* return err for illegal access otherwise fd */
- return((prconfl(openinf.subtype, *access) == ERR)
- ? ERR : openinf.subtype);
-
- case VFS: /* error if directory */
- if(openinf.subtype == DIRECTORY)
- return(ERR);
- }
- /* SHOULD WE CHECK WHETHER FILE IS ALREADY OPEN ??? */
-
- pmode = RWMODE;
-
- /* attempt to create file - if file already exists it will be
- truncated to length zero */
- fd = creat(charnm1, pmode);
-
-
- if(DEBUG) printf("in create after creat : file = <%s> : fd = %d\n",charnm1,fd);
- /* return the file descriptor if fd > MAXFD */
- if(fd > MAXFD) {
- close(fd);
-
- if(DEBUG) printf("in create after close1 : file = <%s> : fd = %d\n",charnm1,fd);
- /* remove zero length file */
- unlink(charnm1);
- return(ERR);
- }
-
- /* return if not created */
- if (fd == -1 )
- return(ERR);
-
- /* reopen with mode access */
- close(fd);
- if(DEBUG) printf("in create after close2 : file = <%s> : fd = %d\n",charnm1,fd);
- fd = open(charnm1, *access);
- if(DEBUG) printf("in create after open : file = <%s> : fd = %d\n",charnm1,fd);
-
- /* opened - initialize file descriptor block */
- ptr = &files[fd];
- strcpy(files[fd].filenam, charnm1);
- ptr -> access = *access;
-
- /* initialize current access to WRITE if write or readwrite
- access requested, READ if read access requested */
- if (*access == READ)
- ptr->caccess = READ;
- else
- ptr->caccess = WRITE;
- ptr -> bufp = ptr -> buffer;
- ptr -> chrleft = 0;
- return (fd) ;
-
- }
-
- error_(string, length)
- char *string;
- long int length;
-
- {
- /* output an error message string to stderr and terminate the
- tool with a call to ZQUIT with status ZERR */
-
- int err = ERR;
-
- remark_(string, length);
- zquit_( &err );
-
- }
-
- getc_(ch)
- int *ch;
-
- {
-
- /* get a single character from the standard input*/
-
- int fd = STDIN;
-
- return ( *ch = getch_(ch, &fd) );
-
- }
-
-
- getch_(ch, fd)
- int *ch, *fd;
-
- {
-
- /* get a single character from the sequential fle
- with file descriptor fd. Trailing blanks i.e.
- those between the last non-space and the final
- newline are stripped out */
-
- struct fdinfo *ptr;
- char c;
-
- /* check for valid fd and file open in read mode */
- if ( opnread(*fd) == ERR )
- return( *ch = ERR );
-
- ptr = &files[*fd];
-
- /* still embedded spaces to pass on ? */
- if (ptr->count > 0) {
- ptr->count--;
- return( *ch = BLANK);
- }
-
-
- /* file open in read mode now */
-
- if (ptr->chrleft == 0) {
-
- /* buffer is empty */
- ptr->chrleft = read(*fd, ptr->buffer, BLOCKSIZE);
- ptr->bufp = ptr->buffer;
-
- /* return EOF if no characters read */
- if (ptr->chrleft == 0) {
- /* throw away spaces if no newline before EOF */
- ptr->count = 0;
- return( *ch = EOF);
- }
- }
-
- /* eat white space refilling the buffer as necessary */
- while ((c = *ptr->bufp++) == BLANKCH) {
- ptr->count++;
- ptr->chrleft--;
-
- if (ptr->chrleft == 0){
- /* if we run out of characters refill the buffer */
- ptr->chrleft = read(*fd, ptr->buffer, BLOCKSIZE);
- ptr->bufp = ptr->buffer;
-
- /* return EOF if no characters read */
- if (ptr->chrleft == 0) {
- /* throw away spaces if no newline before EOF */
- ptr->count = 0;
- return( *ch = EOF);
- }
- }
- }
-
- /* we now have a non-space character and ptr->bufp is pointing
- at the next character although ptr->chrleft hasn't included
- this */
- if (c == NEWLINECH){
- /* possibly training blanks - pointer already on
- next character */
- ptr->count = 0;
- ptr->chrleft--;
- return(*ch = NEWLINE);
- }
- else if (ptr->count == 0) {
- /* decrement count and return character */
- ptr->chrleft--;
- *ch = zcctoi_(&c, ch);
- return(*ch);
- }
- else {
- /* embedded spaces - return a space and decrement space count.
- Backtrack pointer to next non space char, leave the character
- counter alone */
- ptr->bufp--;
- ptr->count--;
- return(*ch = BLANK);
- }
- }
-
- getlin_(buffer, fd)
- int *buffer, *fd;
-
- {
- /* geta line from the sequential file associated with
- the file descriptor fd. The number of characters
- read into buffer including the newline but not the
- eos is returned. If eof was encountered on fd then
- eof is returned. The number of characters read into
- buffer never exceeds maxline although a newline and eos
- may be appended making the maximum length of buffer
- maxbuff */
-
- int i, c;
-
- /* get a line */
- for (i = 1; i <= MAXLINE && (c=getch_(&c,fd)) != NEWLINE && c != EOF
- && c != ERR; *buffer++ = c , i++ );
-
- /* already have maxline characters without a newline */
- if (i > MAXLINE) {
- /* flush the newline or lose character MAXLINE +1 */
- c = getch_(&c, fd);
- *buffer++ = NEWLINE;
- *buffer = EOS;
- return(MAXLINE + 1);
- }
-
- switch (c) {
-
- case NEWLINE:
- *buffer++ = NEWLINE;
- *buffer = EOS;
- return(i);
-
- case EOF:
- *buffer++ = NEWLINE;
- *buffer = EOS;
- return(EOF);
-
- case ERR:
- *buffer = EOS;
- return(ERR);
-
- }
- }
-
-
- open_(name, access)
- int *name, *access;
- {
- /* open an existing sequential file name with access type
- access (=r, w or rw). Assign an internal file descriptor
- and return it as the value of the function. It is illegal
- to try and open a file which does not exist */
-
- int fd;
- struct filinfo openinf;
- char charnm1[MAXPATH];
-
- /* generate full path name as a character string */
- mkfilnm(name, charnm1, &openinf);
-
- /* sort out possible error cases */
- switch (openinf.ftype1)
- {
- case ERR: /* error in mkpath or host file a directory */
- return(ERR);
-
- case DEVICE: /* return err for illegal access otherwise fd */
- return((prconfl(openinf.subtype, *access) == ERR)
- ? ERR : openinf.subtype);
-
- case HOST: /* error if file doesn't exist */
- if(openinf.exists == NO) return(ERR);
- break;
-
- case VFS: /* error if file doesn't exist or directory */
- if(openinf.exists == NO || openinf.subtype == DIRECTORY)
- return(ERR);
- }
-
- /* ensure open ok and not too many descriptors */
- if((fd=open(charnm1, *access)) == -1 ) return(ERR);
-
- if(DEBUG) printf("in open : file = <%s> : fd = %d\n",charnm1,fd);
- if (fd > MAXFD) {
- close(fd);
- if(DEBUG) printf("in open after close1 : file = <%s> : fd = %d\n",charnm1,fd);
- return(ERR);
- }
-
- /* store file info and initialize buffers etc. */
- strcpy(files[fd].filenam, charnm1);
- files[fd].ftype = SEQUENTIAL;
- files[fd].access = *access;
-
- /* set current access to READ if access is read or readwrite
- and to WRITE if access is write */
- if (*access == WRITE)
- files[fd].caccess = WRITE;
- else
- files[fd].caccess = READ;
-
- files[fd].chrleft = 0;
- files[fd].bufp = files[fd].buffer;
- return(fd);
-
- }
-
- /* void */
- putc_(ch)
- int *ch;
-
- {
- /* put a character out on the standard output file stdout */
- int fd = STDOUT;
- putch_(ch, &fd);
-
-
- }
-
-
- putch_(ch, fd)
- int *ch, *fd;
-
- {
-
- /* put a character out to a sequential file with
- file descriptor fd. Output is buffered until
- the buffer is full or the program terminates */
-
- struct fdinfo *ptr;
-
- /* check for valid fd and file open in write mode */
- if ( opnwrit( *fd ) == ERR )
- return;
-
- ptr = &files[*fd];
-
- /* file open in write mode now */
-
- if (ptr->chrleft == MAXLINE) {
-
- /* buffer is full append newline and flush */
- *ptr->bufp = NEWLINE;
- ptr->chrleft++;
-
- /* delete any trailing spaces before NEWLINE */
- ptr->chrleft = fndnblk(ptr->bufp, ptr->chrleft);
-
- /* and write out the buffer */
- write(*fd, ptr->buffer, ptr->chrleft);
- ptr->chrleft = 0;
- ptr->bufp = ptr->buffer;
- /* if current character a NEWLINE then return as it
- has already been output */
- if (*ch == NEWLINE) return;
- }
-
- /* store character in buffer */
- *ptr -> bufp ++ = *ch;
- ptr->chrleft ++;
-
- /* flush buffers on a newline */
- if (*ch == NEWLINE) {
- /* delete any trailing spaces before NEWLINE */
- ptr->bufp--;
- ptr->chrleft = fndnblk(ptr->bufp, ptr->chrleft);
- write(*fd, ptr->buffer, ptr -> chrleft);
- ptr->chrleft = 0;
- ptr->bufp = ptr->buffer;
-
- }
- }
-
-
- putdec_( value, width)
- int *value, *width;
-
- {
- /* write the number value out to stdout in a field of width
- width. If the length of the number as a string is <=
- width it is blank filled right justified, else the number
- is output in a wider field */
-
- int fd = STDOUT;
-
- zptint_(value, width, &fd);
-
- }
-
- putlin_(buffer, fd)
- int *buffer, *fd;
-
- {
- /* output the string in buffer (terminated by eos) to
- the file associated with the file descriptor fd */
-
- int c;
-
- while ((c = *buffer++) != EOS)
- putch_(&c, fd);
-
- }
-
-
- readf_( buf, count, fd)
- int *buf, *count, *fd;
-
- {
- /* read count characters from the file with associated
- file descriptor fd into buf and terminate with an
- EOS character. This routine has no way of indicating
- a read past end of file.
-
- WARNING: use GETLIN or ZGTCMD in preference */
-
- int i, c;
-
- for (i = 1; i <= *count && (*buf++ = getch_(&c, fd)) != EOF; i++);
-
- if (c == EOF )
- buf--;
-
- *buf = EOS;
-
- }
-
- remark_(s, length)
- char *s;
- long int length;
-
- {
- /* output an f77 string up to but not including a terminating
- PERIOD to STDERR. If no terminating period all length
- characters are output. A period within a string is denoted
- by '..' */
-
- int fd = STDERR, newline = NEWLINE;
- struct fdinfo *ptr;
-
- /* make sure that STDERR is OK to write to. This is done in
- putch but if things get screwed there is the possibility of
- an endless call putch loop - the next statement is a panic
- exit */
- ptr = &files[STDERR];
-
- if (ptr->access == NOTOPEN || ptr->access == READ) exit(1);
-
- /* if the above checks are OK the following putch's should be
- ok i.e. they won't result in another call to remark */
-
- zchout_(s, &fd, length);
- putch_( &newline, &fd);
-
- }
-
- remove_(name)
- int *name;
- {
-
- /* delete the closed file name from the directory. This routine
- may be used to remove either a sequential or a direct access
- file */
-
- int fd;
- char charnm1[MAXPATH];
- struct fdinfo *ptr;
- struct filinfo openinf;
-
- mkfilnm(name, charnm1, &openinf);
-
- /* can't remove device file and return on filename error */
- switch (openinf.ftype1)
- {
- case ERR:
- return;
-
- case DEVICE:
- return;
-
- case VFS :
- if (openinf.subtype == DIRECTORY) return;
- break;
-
- }
- /* if it doesn't exist there's no need to delete it */
- if (openinf.exists != YES) return;
-
- /* close the file if it is open */
- for (fd = FIRSTFD; fd < MAXFILE; fd++)
- { ptr = &files[fd];
- if (ptr->access != NOTOPEN && strcmp( ptr -> filenam, charnm1) == 0)
- close_(&fd);
- }
-
- /* remove the file */
- unlink(charnm1);
- return;
-
- }
-
- seek_(pos, fd)
- int *pos, *fd;
- {
- /* despite what the documentation says this routine
- effects a rewind on channel fd.
- It has no effect on preconnected files */
-
- struct fdinfo *ptr;
-
- ptr = &files[*fd];
-
- if (checkfd(*fd) != FILES || files[*fd].access == NOTOPEN)
- return;
-
- /* move the file pointer back to the begining of the file */
- ptr -> chrleft = 0;
- ptr -> count = 0;
- ptr -> bufp = ptr ->buffer;
- lseek(*fd,(long)(*pos),0);
-
-
- }
-
- skip_(lines)
- int *lines;
-
- {
- /* output lines blank lines to stdout */
-
- int i, newline = NEWLINE, fd = STDOUT;
-
- for(i = 1; i <= *lines; i++)
- putch_( &newline, &fd);
-
- }
-
- zbcret_(name, maxrec)
- int *name, *maxrec;
- {
-
- /* create a direct access file with a maximum of MAXREC records
- The file is to contain fixed length records of length MAXBUFF.
- Any existing file, name, is deleted (truncated to length zero).
-
- The first record in the file is to contain the maximum record
- number.
-
- The file descriptor is returned or ERR if create fails. */
-
- int uid,gid,len,i;
- char newch[MAXPATH];
- struct stat sbuf;
-
-
- struct fdinfo *ptr;
- struct filinfo openinf;
- char charnm1[MAXPATH];
- int fd, junk, iststr[MAXBUFF];
- int access = READWRITE;
-
- /* generate full path name as a character string */
- mkfilnm(name, charnm1, &openinf);
-
- /* sort out possible error cases */
- switch (openinf.ftype1)
- {
- case ERR: /* error in mkpath or host file a directory */
- return(ERR);
-
- case DEVICE: /* return err for illegal access otherwise fd */
- return((prconfl(openinf.subtype, access) == ERR)
- ? ERR : openinf.subtype);
-
- case VFS: /* error if directory */
- if(openinf.subtype == DIRECTORY)
- return(ERR);
- }
- /* SHOULD WE CHECK WHETHER FILE IS ALREADY OPEN ??? */
-
-
-
- /* attempt to create file - if file already exists it will be
- truncated to length zero */
- fd = creat(charnm1, RWMODE);
-
- /* return the file descriptor if fd > MAXFD */
- if(fd > MAXFD) {
- close(fd);
- /* remove zero length file */
- unlink(charnm1);
- return(ERR);
- }
-
- /* return if not created */
- if (fd == -1 )
- return(ERR);
- /* close and reopen in readwrite mode */
- close(fd);
- fd = open(charnm1, READWRITE);
-
- /* set up file descriptor block */
- ptr = &files[fd];
- ptr->bufp = ptr->buffer;
- ptr->ftype = DIRECT;
- ptr->chrleft = *maxrec;
- ptr->access = READWRITE;
- strcpy(ptr->filenam, charnm1);
-
- /* write maximum number of records to first record of file */
- junk = MAXBUFF;
- itoc_(maxrec, &iststr[0], &junk);
-
- /* switch on access to record zero */
- opnrec0 = 1;
-
- /* put the first record into the file */
- junk = 0;
- zbputr_(&fd, &junk, &iststr[0]);
-
- /* switch off access to record 0 */
- opnrec0 = 0;
- /* return the file descriptor */
- return(fd);
-
- }
-
- zbgetr_(fd, recnum, buf)
- int *fd, *recnum, *buf;
- {
-
- /* read the contents of record number recnum from the direct access file
- associated with the file descriptor fd into buf.
- It is an error to use a invalid recnum or attempt
- to access a sequential file. buf must be of size MAXBUFF
- to prevent the overwriting of data areas.
- Reading a record that has not previously been written will
- result in a buf vector filled with nulls */
-
- struct fdinfo *ptr;
- unsigned char ch;
- char *ptc;
- int junk, i;
- long int recpos;
-
- /* check file descriptor is FILES ie not out of range
- or one of the preconnected units and associated file is open */
- if (checkfd(*fd) != FILES || files[*fd].access == NOTOPEN) return(ERR);
-
- /* check file open for direct access */
- if (files[*fd].ftype != DIRECT) return(ERR);
-
- /* check record number is in range */
- /* opnrec0 = 1 allows access to record zero only this
- is only set by zbopen */
- if (opnrec0 == 0 && chkrnum(*recnum, *fd) == ERR) return(ERR);
-
- ptr = &files[*fd];
- ptc = ptr -> buffer;
-
- /* find the required position in the file */
- recpos = *recnum * MAXBUFF;
- lseek(*fd, recpos, 0);
-
- /* read into fdinfo buffer */
- read(*fd, ptr->buffer, MAXBUFF);
-
- /* and convert each character to its equivalent IST character */
- for (i=0; i<MAXBUFF; i++){
- /* don't interpret the sign bit as a sign !! */
- ch = *ptc++;
- *buf++ = ch;
- }
-
- return(NOERR);
-
- }
-
- zbopen_(name, maxrec)
- int *name, *maxrec;
- {
-
- /* open a preexisting direct access file and return the maximum
- record number allowed. The file is for fixed length (MAXBUFF)
- formatted records.
- The maximum record number is stored in the first record in the
- file. Direct access files are always opened/created in
- READWRITE MODE */
-
- struct filinfo openinf;
- char charnm1[MAXPATH];
- int fd, temp;
- int buffer[MAXBUFF]; /* local buffer used for storing value of maxrec */
- int access = READWRITE;
-
- /* generate full path name as a character string */
- mkfilnm(name, charnm1, &openinf);
-
- /* sort out possible error cases */
- switch (openinf.ftype1)
- {
- case ERR: /* error in mkpath or host file a directory */
- return(ERR);
-
- case DEVICE: /* return err for illegal access otherwise fd */
- return((prconfl(openinf.subtype, access) == ERR)
- ? ERR : openinf.subtype);
-
- case HOST: /* error if file doesn't exist */
- if(openinf.exists == NO) return(ERR);
- break;
-
- case VFS: /* error if file doesn't exist or directory */
- if(openinf.exists == NO || openinf.subtype == DIRECTORY)
- return(ERR);
- }
-
- /* ensure file exists and not too many descriptors */
- if((fd=open(charnm1, READWRITE)) == -1 ) return(ERR);
- if (fd > MAXFD) {
- close(fd);
- return(ERR);
- }
-
- /* store file info */
- strcpy(files[fd].filenam, charnm1);
- files[fd].ftype = DIRECT;
- files[fd].access = READWRITE;
-
-
- /* switch on access to record zero */
- opnrec0 = 1;
-
- /* get first record, return value of maxrec and store it for
- future gets and puts in chrleft */
- temp = 0;
- zbgetr_(&fd, &temp, &buffer[0]);
- temp = 1;
-
- /* switch off access to record zero */
- opnrec0 = 0;
- /* a value of zero probably indicates access of a sequential file */
- if( (*maxrec = ctoi_(&buffer[0], &temp)) == 0) {
- close(fd);
- return(ERR);
- }
- files[fd].chrleft = *maxrec;
-
- return(fd);
- }
-
- zbputr_(fd, recnum, buf)
- int *fd, *recnum, *buf;
- {
-
- /* write the contents of buf to the direct access file
- associated with the file descriptor fd at record number
- recnum. It is an error to use a invalid recnum or attempt
- to access a sequential file. buf must be of size MAXBUFF
- and may contain any valid IST characters including embedded
- EOS and NEWLINE characters. Any value in buf outside the
- range 0-255 will be stored as zero */
-
- struct fdinfo *ptr;
- char *ptc;
- int c, i;
- long int recpos;
-
- /* check file descriptor is FILES ie not out of range
- or one of the preconnected units and associated file is open */
- if (checkfd(*fd) != FILES || files[*fd].access == NOTOPEN) return(ERR);
-
- /* check file open for direct access */
- if (files[*fd].ftype != DIRECT) return(ERR);
-
- /* check record number is in range */
- /* unless permission to access record zero is set */
- if ( opnrec0 == 0 && chkrnum(*recnum, *fd) == ERR) return(ERR);
-
- ptr = &files[*fd];
- ptc = ptr -> buffer;
-
- /* find the required position in the file */
- recpos = *recnum * MAXBUFF;;
- lseek(*fd, recpos, 0);
-
- /* write IST string to fdinfo buffer */
- for (i=0; i<MAXBUFF; i++)
- {
- if ( (c = *buf++) > 255 || c < 0) c = 0;
- *ptc++ = c;
- }
-
- /* and thence to the file */
- write(*fd, ptr->buffer, MAXBUFF);
-
- return(NOERR);
-
- }
-
- zchout_(s, fd, length)
- char *s;
- int *fd;
- long int length;
-
- {
- /* output an f77 string terminated by a period to the file associated
- with the file descriptor fd. No trailing NEWLINE is appended to
- the line and the period is not transmitted. A period within the
- string is denoted by '..' */
-
- char *ptr ;
- char period = PERIODCH;
-
- /* set pointer to end of string */
-
- ptr = s+length-1;
-
- /* loop through the string */
-
- while (s < ptr)
- {
- /* take care of double period case */
- if( *s == PERIODCH && *(s+1) == PERIODCH )
- {
- zputch_( &period, fd);
- s += 2;
- }
-
- /* single PERIOD - return */
- else if (*s == PERIODCH)
- return;
-
- /* else output the character */
- else
- zputch_(s++, fd);
- }
-
- /* deal with last character either PERIOD (ignore)
- or character (output) */
- if(*ptr != PERIODCH)
- zputch_( ptr,fd);
-
- }
-
- zcntrl_(fd, leni, leno, flag)
- int *fd, *leni, *leno, *flag;
- {
-
- /* Change the handling of input and output strings for all future
- sequential i/o with associated file descriptor fd. Allows the
- user to control the input record length, the output record length,
- and the backspace processing for each channel. Backspace
- processing consists of checking each line for backspaces
- and removing both them and the preceding charcater, i.e. treating
- them as character deletes. Any invalid argument values are
- ignored and result in no change to that parameter */
-
- remark_("Routine ZCNTRL not implemented in this version of TIE",53L);
- }
-
- zcrdir_(name)
- int *name;
- {
-
- /* create a new directory with name name in the local directory.
- No path names are allowed
- The name name must be unique in this directory */
-
- int mode = RWXMODE;
- char charnm1[MAXPATH];
- struct filinfo finf;
-
- /* create character file name and check it is a simple name */
- istchr_(name, charnm1);
- if (isaname(charnm1) == NO) return(ERR);
-
- /* generate full path name */
- mkfilnm(name,charnm1,&finf);
-
- /* return if name exists, name is a device or name is erroneous */
- if (finf.exists == YES || finf.ftype1 == DEVICE || finf.ftype1 == ERR)
- {
- return(ERR);
- }
-
- /* system call */
- if (mkdir(charnm1, mode) == -1) return(ERR);
-
- return(NOERR);
-
- }
-
- zdldir_(name)
- int *name;
- {
-
- /* delete an empty directory with name name in the local directory. */
-
- char charnm1[MAXPATH];
- struct filinfo finf;
-
- /* create character file name and check it is a simple name */
- istchr_(name, charnm1);
- if (isaname(charnm1) == NO) return(ERR);
-
- /* generate a full path name */
- mkfilnm(name, charnm1, &finf);
-
- /* return if not a directory */
- if (finf.subtype != DIRECTORY) return(ERR);
-
- /* disallow deletion of root and root/ */
- if (strcmp(root, charnm1)==0 ||
- strcmp(strcat(root,"/"), charnm1)==0 ) return(ERR);
-
- /* system call */
- if (rmdir(charnm1) == -1) return(ERR);
-
- return(NOERR);
-
- }
-
- zftype_(name, sequen)
- int *name, *sequen;
- {
-
- /* Discover the type of the entity with the pathname name.
- This routine returns ERR (file does not exist or illegal
- file name), host, device (preconnected unit), plain
- (vfs file) or directory (vfs directory) */
-
- struct filinfo finf;
- char charnm1[MAXPATH];
-
- /* on UNIX the file is always sequential */
- *sequen = YES;
-
- mkfilnm(name, charnm1, &finf);
-
- /* deal with the error case first */
- if (finf.ftype1 == ERR || finf.exists == NO) return(ERR);
-
- /* vfs file */
- if (finf.ftype1 == VFS) return(finf.subtype);
-
- /* host files or devices */
- return(finf.ftype1);
- }
-
- zgetch_(c,fd)
- char *c;
- int *fd;
- {
- /* get an f77 character from the sequential file associated
- with the file descriptor fd and return it in c. The IST
- equivalent value is returned via the function name */
-
- int inch;
- char ch;
-
- inch = getch_(&inch, fd);
- if(inch != EOF && inch != ERR)
- zcitoc_(c, 1L, &inch, &ch);
-
- return(inch);
-
- }
-
- zgetln_(buf, fd)
- char *buf;
- int *fd;
- {
- /* get an f77 character string from the sequential file
- associated with the file descriptor fd and return it
- in buf. The number of valid characters in the string
- is returned through the function. The string may or
- may not be terminated by an odd number of '.' as required
- by ZCHOUT and ZMESS */
-
- char ch;
- int val, i;
-
- /* read characters until a newline, end of file, error or
- maxbuff characters read */
- for(i = 1; i<=MAXBUFF && (val = zgetch_(&ch, fd)) != NEWLINE
- && val != EOF && val != ERR ; *buf++ = ch , i++) ;
-
- /* return the length of the string or the error or end of
- file value */
- return ((val==EOF || val==ERR) ? val : i-1);
-
- }
-
- zgtcmd_(arg, fd)
- int *arg, *fd;
-
- {
- /* get a line of information from the file associated
- with the file descriptor fd using getlin. Strip off
- the trailing NEWLINE and return the length of the
- resulting string ( or ERR or EOF) */
-
- int n;
-
- n = getlin_(arg, fd);
-
- /* order of evaluation guaranteed left to right */
-
- if ( n != ERR && n != EOF && *(arg+n-1) == NEWLINE)
- *(arg + --n) = EOS;
- return ( n );
-
- }
-
- zinstr_(str, n, fd)
- int *str, *n, *fd;
- {
-
- /* read a line of n IST characters into the array str from
- the file associated with the file descriptor fd.
-
- If n<=0 read up to and including the first NEWLINE
- if no characters can be read return a single NEWLINE
-
- If n>0 return the first n characters - there is no
- guarantee that the last character will be a NEWLINE
-
- WARNING : Use GETLIN or ZGTCMD in preference */
-
- int i, c;
-
- /* n positive */
-
- if ( *n > 0)
- {
- for (i = 1; i <= *n && (c=getch_(&c, fd)) != ERR && c != EOF;
- i++)
- *str++ = c;
- if (c == ERR)
- return(ERR);
- else
- return(i-1);
- }
-
- /* n negative - while loop takes care of EOF on first character */
-
- i = 0;
- while ((c = getch_(&c, fd)) != NEWLINE && c != EOF && c != ERR)
- {
- i++;
- *str++ = c;
- }
-
- if ( c == ERR)
- return(ERR);
-
- *str++ = NEWLINE;
- *str = EOS;
-
- return(i+1); /* includes the NEWLINE character */
-
- }
-
-
- zlocal_(name)
- int *name;
- {
-
- /* change the local directory to that specified by name. Resets
- the directory reading pointer to the start of the local
- directory entry table. If name is null the root is selected */
-
- char charnm1[MAXPATH], temp[MAXPATH];
- char *ptr;
- struct filinfo finf;
- int status;
- DIR *opendir();
-
- /* set global directory read error flag */
- direrr = NOERR;
- /* deal with null name and "/" */
- if (*name == EOS || ( *name == SLASHCH && *(name+1) == EOS)) {
- strcpy(lcldir, "");
- /* open the root directory */
- /* close directory stream if one open before opening a new one */
- if (dirp != (DIR*) NULLST)closedir(dirp);
- dirp = opendir(root);
- if (dirp == (DIR*) NULLST) direrr = ERR;
- }
-
- else {
- istchr_(name, temp);
- /* convert pathname to lower case and strip
- leading white space */
- for (ptr = temp; *ptr == BLANKCH || *ptr == TABCH ;ptr++);
- while (*ptr != EOSCH) {
- *ptr = ( isupper(*ptr) ? tolower(*ptr) : *ptr );
- ptr++;
- }
- if ((status = mkpath(temp, charnm1)) == ERR) return(ERR);
-
- /* check path exists and is a directory */
- if(DEBUG)printf(" in zlocal - charnm1 = %s\n",charnm1);
- if (isadir(charnm1) == NO) return(ERR);
- if(DEBUG)printf(" in zlocal isadir returns %d\n",isadir(charnm1));
-
-
- /* open directory stream */
- /* close directory stream if one open before opening a new one */
- if (dirp != (DIR*) NULLST)closedir(dirp);
- dirp = opendir(charnm1);
- if (dirp == (DIR*) NULLST) direrr = ERR;
-
- /* strip off root and SLASH and copy to localdir */
- ptr = charnm1 + strlen(root) + 1;
- strcpy(lcldir, ptr);
-
- }
-
- return(NOERR);
-
- }
-
- zmess_(s, fd, length)
- char *s;
- int *fd;
- long int length;
- {
-
- /* output an f77 string terminated by a period to the file
- associated with the file descriptor fd. A trailing NEWLINE is
- appended to the line. A period is denoted by '..' */
-
- int newline = NEWLINE;
-
- zchout_(s, fd, length);
- putch_( &newline, fd);
-
- }
-
- zoblnk_(n, fd)
- int *n, *fd;
- {
-
- int i, blank = BLANK;
-
- /* output n blanks to the file fd */
-
- for (i = 1; i<=*n ; i++)
- putch_( &blank, fd);
-
- }
-
- zpos_(pos,fd)
- int *pos, *fd;
-
- {
- /* move the file pointer of the sequential file associated
- with the file pointer fd to a new character position.
- The next read (write) operation on this file will read
- (write) the next character after pos (relative to the
- current pointer).
- Note that a position request of 1 will skip a character.
- A negative value of pos has no effect.
- Positioning a device file has no effect. */
-
- /* UNIX DEPENDENT */
-
- /* repositioning the file pointer when the file is open for
- writing will effectively result in a sequence of nulls
- being written into the hole */
-
- long int offset;
- struct fdinfo *ptr;
- int nchars;
-
- /* check for valid file descriptor */
- if ( checkfd(*fd) != FILES ) return;
-
- if (*pos <= 0 ) return;
- ptr = &files[*fd];
-
- /* if open in write mode dump the current buffer
- - you get what you deserve as far as trailing
- blanks are concerned ! */
- if(ptr -> caccess == WRITE){
- write(*fd, ptr->buffer, ptr->chrleft);
- offset = *pos;
- }
-
- else { /* current access to file is READ */
-
- /* calculate the real current position within the file by
- taking into account the buffer contents */
- nchars = ptr->count + ptr->chrleft;
- if (*pos < nchars) {
-
- /* repositioning is still within the buffer */
- if (*pos <= ptr->count) {
- /* repositioning is still within a
- block of blanks */
- ptr->count -= *pos;
- return;
- }
- else {
- /* reposition within buffer */
- nchars = *pos - ptr->count;
- ptr->count = 0;
- ptr->chrleft -= nchars;
- ptr->bufp += nchars;
- return;
- }
- }
-
- else
- /* need to reposition using lseek */
- offset = *pos - nchars;
- }
-
- /* zero counts etc ready for next read/write to file */
- ptr-> chrleft = 0;
- ptr->count = 0;
- ptr->bufp = ptr->buffer;
- lseek(*fd, offset, 1);
-
- }
-
- xputc_(ch)
- int *ch;
-
- {
- /* put a character out on the standard output file stdout */
-
- /* implemented as single character output for prompts */
- char c, junk;
- zcitoc_(&c,1L,ch,&junk);
- write(STDOUT, &c, 1);
-
- }
-
- zprmpt_(s)
- int *s;
- {
-
- char c,junk;
- /* output the IST string s to stderr - without adding a
- trailing NEWLINE */
-
- while(*s != EOS){
- zcitoc_(&c,1L,s,&junk);
- s++;
- write(STDERR,&c,1);
- }
- }
-
- zptint_(value, width, fd)
- int *value, *width, *fd;
-
- {
- /* write the number value out to the sequential file
- associated with the file descriptor fd in a field
- of width width. If the length of the number as a
- string is <= width it is blank filled and right
- justified, else the number is output in a wider field */
-
- int ist[MAXLINE], length;
-
- /* convert number to IST string */
- length = MAXLINE;
- length = itoc_(value, &ist[0], &length);
-
- /* output the requisite number of blanks */
- length = *width - length;
- zoblnk_(&length, fd);
- putlin_(&ist[0], fd);
-
- }
-
- zptmes_(buffer, fd)
- int *buffer, *fd;
- {
-
- int newline = NEWLINE;
-
- /* put a message out on the sequential file fd */
-
- putlin_(buffer, fd);
- putch_( &newline, fd);
-
- }
-
- zptstr_(string, width, fd)
- int *string, *width, *fd;
- {
-
- /* output the string string to the sequential file with
- associated file descriptor fd and justified in a field of width width
-
- width > 0 => string right justified
- width < 0 => string left justified
-
- length(string) > abs(width) => normal output */
-
- int len, i, blank = BLANK;
-
- len = length_(string);
-
- /* width > 0 output leading spaces for right justification */
- if (width >= 0)
- for (i=len+1; i <= *width; i++) putch_(&blank, fd);
-
- /* right justify output string after leading blanks
- left justify output string ( width < 0 ) */
- while (*string != EOS) {
- putch_(string, fd);
- string++;
- }
-
- /* right justify now finished */
- if (width >= 0) return;
-
- /* left justify - output trailing blanks */
- for (i=len+1; i<= -*width; i++) putch_(&blank, fd);
- return;
-
- }
-
- zputch_(ch, fd)
- int *fd;
- char *ch;
- {
-
- /* output an f77 character to the file associated with the file
- descriptor fd */
-
- int junk;
-
- junk = zcctoi_(ch, &junk);
- putch_(&junk, fd);
-
- }
-
- zrddir_(name)
- int *name;
- {
-
- /* returns the name of the next entry in the local directory.
- This is a sequential operation, to restart reading a
- directory it is necessary to call zlocal. On UNIX we
- ignore "." and ".." */
-
- #ifdef HPUX
- struct dirent *dp, *trddir();
- #else
- struct direct *dp, *trddir();
- #endif
-
- /* check the global error flag */
- if (direrr == ERR) return(ERR);
-
- /* get the next entry and check it isn't "." or ".." */
-
- /* use a system call */
- while (((dp = readdir(dirp)) != NULLST) && (strcmp(dp->d_name, ".") ==0
- || strcmp(dp->d_name, "..") == 0));
- /* if NULLST have we an EOF condition */
- if (dp == NULLST) {
- direrr = EOF;
-
- return(EOF);
- }
-
- /* otherwise return the name */
- chist_(dp->d_name, name, strlen(dp->d_name));
- direrr = NOERR;
- return(NOERR);
- }
-
- zrenam_(path1, path2)
- int *path1, *path2;
- {
-
- /* Rename a file. the file referred to by path1 is renamed path2.
- path1 and path2 must be of the same type ('host' or 'plain')
- and path1 must exist while path2 must not exist */
-
- int pid, status, w;
- struct filinfo finf1, finf2;
- char file1[MAXPATH], file2[MAXPATH];
-
- /* generate full path anmes */
- mkfilnm(path1, file1, &finf1);
- mkfilnm(path2, file2, &finf2);
-
- /* check for valid move both host files or both plain files */
- if ((finf1.ftype1 == HOST && finf2.ftype1 == HOST) ||
- (finf1.ftype1 == VFS && finf2.ftype1 == VFS &&
- finf1.subtype == PLAIN && finf2.subtype == PLAIN)) {
-
- /* check file1 exists and file2 does not */
- if (finf1.exists == NO || finf2.exists == YES) return(ERR);
- if ((pid = fork()) == -1) return(ERR);
-
- if (pid == 0) execl(MVPATH, "mv", file1, file2, (char *)0);
- while ((w = wait(&status)) != pid && w != -1);
-
- if( w == -1) return(ERR);
-
- return(NOERR);
- }
-
- /* invalid arguments */
- return(ERR);
-
- }
-
- zspool_()
- {
-
- /* close the current standard list file and open a new one.
- Flush buffer associated with fd = STDLST.
- Print file using lpr with flags LPRFLAGS.
- Start a new spool file */
-
- struct stat buf;
- int access = READWRITE, istname[MAXPATH];
- int fd = STDLST;
- int pid, status, w;
-
- close(fd);
-
- /* don't list it if it doesn't exist (impossible !?) or is empty */
- if (stat(files[fd].filenam, &buf) != -1 && buf.st_size > 0) {
-
- if ((pid = fork()) == -1) return(ERR);
-
- if (pid == 0) {
- execl(LPRPATH, LPR, files[fd].filenam, (char *)0);
- exit(1);
- }
- while ((w = wait(&status)) != pid && w != -1);
-
- if( w == -1) return(ERR);
- }
-
- /* create a fresh spool file */
- status = crtzlng(files[fd].filenam, access, fd);
- if (status != fd) remark_("spooler file recreation error.",30L);
- if (status != fd) printf("status,fd = %d , %d \n",status,fd);
-
- return(NOERR);
-
- }
-
- zstamp_(path, date, time)
- int *path, *date, *time;
- {
-
- /* Return the last modified date and time stamps of the specified
- file or directory in the PFS. It is an error to try to get the
- time stamp for a host or non-existant file. The time stamp
- may be converted to an IST string using the routine ZTIMES. The
- date and time values are calculated as follows
-
- DATE = ((year - 1983)*13 + month)*32 + day
- TIME = (hour*61 + minute) *61 + second
- */
-
- struct tm tmstr, *localtime();
- struct stat buf;
- struct filinfo finf;
- char charnm1[MAXPATH];
-
- /* get the file information */
- mkfilnm(path, charnm1, &finf);
- if (finf.ftype1 != VFS || finf.exists != YES) return(ERR);
-
- /* get the last modified time */
- stat(charnm1, &buf);
- zstclk = buf.st_mtime;
- tmstr = *localtime(&zstclk);
-
- *date = ((tmstr.tm_year - 83)*13 + tmstr.tm_mon)*32 +
- tmstr.tm_mday;
-
- *time = (tmstr.tm_hour*61 + tmstr.tm_min)*61 + tmstr.tm_sec;
-
- return(NOERR);
-
- }
-
- zstate_(name)
- int *name;
- {
-
- /* find the status of the file name. This routine may be used to
- find the status of a direct access or sequential files
- N.B. you can't tell the difference on UNIX
-
- Preconnected units always exist */
-
- struct filinfo finf;
- char charnm1[MAXPATH];
-
- mkfilnm(name, charnm1, &finf);
-
- /* invalid file type */
- if (finf.ftype1 == ERR) return(ERR);
-
- /* Preconnected unit */
- if (finf.ftype1 == DEVICE) return(YES);
-
- /* exists or not */
- return(finf.exists);
-
- }
-
- ztidy_()
- {
-
- /* close all sequential and direct access files currently
- open to this program */
-
- int fd;
-
- for (fd = FIRSTFD; fd < MAXFILE ; fd++) close_(&fd);
-
- }
-
- ztouch_(path)
- int *path;
- {
-
- /* update the time stamp for a specified plain or directory
- file. It is an error to try to update the time stamp
- of a host or non-existant file */
-
- struct filinfo finf;
- char filenam[MAXPATH];
- int pid, status, w;
-
- mkfilnm(path, filenam, &finf);
-
- /* check exists and is in the vfs */
- if (finf.ftype1 != VFS || finf.exists != YES) return(ERR);
-
- {
- struct timeval tvp[2];
- struct timezone tz;
-
- gettimeofday(tvp, &tz);
- tvp[1] = tvp[0];
- #ifdef HPUX /*+++*/
- utime(filenam,tvp); /*+++*/
- #else /*+++*/
- utimes(filenam, tvp);
- #endif /*+++*/
- }
-
-
- return(NOERR);
-
- }
-